/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.module.CanvasPanel', {
	extend: 'Ext.panel.Panel',
	mixins: {
		image: 'SvgEditor.graph.Image',
		circle: 'SvgEditor.graph.Circle',
		ellipse: 'SvgEditor.graph.Ellipse',
		path: 'SvgEditor.graph.Path',
		rect: 'SvgEditor.graph.Rect',
		anchor: 'SvgEditor.graph.Anchor',
		text: 'SvgEditor.graph.Text',
		selectBox: 'SvgEditor.canvas.SelectBox',
		keyMap: 'SvgEditor.canvas.KeyMap',
		operation: 'SvgEditor.canvas.Operation'
	},
	autoScroll: true,
	layout: 'absolute',
	locale: null,
	util: null,
	treeStore: null,
	paper: null,
	quickbar: null,
	readOnly: false,
	nowId: 0,
	modelIds: [],
//	img: null,
	enableDragDrop: true,
	origin: {offsetX: 0, offsetY: 0},
	anchor: {startP: null, endP: null, knuckles: []},
	selected: [],
	takeUp: null,
	target: null,
	ClipBoard: null,
	modelSet: null,
	data: {},
	initComponent: function() {
		var me = this;
		if (!me.readOnly) {
			me.initTextView(me);
//		me.img = Ext.create('Ext.Img');
			me.quickbar = me.tbar = Ext.create('SvgEditor.canvas.Quickbar', {canvas: me, locale: me.locale});
			me.widget = Ext.create('SvgEditor.canvas.Widget', {hidden: true, canvas: me});
			me.items = [me.textView, me.widget];//, me.img];
		}
		me.callParent();
	},
	initTextView: function(me) {
		me.textView = Ext.create('Ext.form.field.TextArea', {
			hidden: true,
			thisModel: null,
			width: 100,
			rows: 3,
			focused: false,
			setText: function(model) {
				var text = this.getValue();
				if (model.text && this.isDirty()) {
					model.text.attr({text: text});
				} else {
					var bbox = model.getBBox(), textConfig = {
						type: 'text',
						attrs: {
							x: model.coreX, y: bbox.y2 + 10,
							text: text, font: "14px 宋体"
						}
					};
					model.text = me.createModel(me, textConfig);
					model.text.model = model;
				}
				model.data('text', text);
			},
			getText: function(model) {
				var text = model.data('text');
				this.setValue(text);
			},
			listeners: {
				blur: {
					fn: function() {
						this.setText(this.thisModel);
						this.thisModel = null;
						this.reset();
						this.hide();
						this.focused = false;
					}
				},
				focus: {
					fn: function() {
						this.focused = true;
						this.thisModel = me.selected[0];
						this.getText(this.thisModel);
						me.widget.setX(me.selectBox.attrs.x + me.origin.offsetX - me.widget.getWidth());
					}
				}
			}
		});
	},
	afterFirstLayout: function() {
		var me = this;
		me.initCanvas(me);
		me.layout.outerCt.setHeight(0);
	},
	initCanvas: function(me) {
		if (me.paper) {
			me.modelSet = me.paper.setFinish();
			Ext.each(me.modelSet, function(model) {
				model.removeData();
				if (model.text) {
					model.text.remove();
				}
				if (model.flowPlate) {
					model.flowPlate.remove();
				}
				model.remove();
			});
			me.anchor.startP.remove();
			me.anchor.endP.remove();
			Ext.each(me.anchor.knuckles, function(knuckle) {
				knuckle.remove();
			});
			me.anchor.knuckles = [];
			if (me.selectBox) {
				me.selectBox.remove();
			}
			if (me.lineX && me.lineY) {
				me.lineX.remove();
				me.lineY.remove();
			}
			me.paper.remove();
		}
		me.nowId = 0;
		me.modelIds = [];
//		me.paper = Raphael(me.body.id, me.getWidth(), me.getHeight());
		var width = me.getWidth(), height = me.getHeight;
		width = width > 1000 ? width : 1000;
		height = height > 1000 ? height : 1000;
		me.paper = Raphael(me.body.id, width, height);
		me.paper.renderfix();
		me.origin.offsetX = me.getX();
		me.origin.offsetY = me.getY();
		if (me.quickbar) {
			me.origin.offsetY += me.quickbar.getHeight();
		}
		var anchorConfig = {
			modelId: null,
			type: 'circle',
			attrs: {
				r: 3, fill: 'white', 'fill-opacity': 0
			}
		};
		anchorConfig.modelId = 'startP';
		me.anchor.startP = me.mixins.anchor.init(me, anchorConfig).hide();
		anchorConfig.modelId = 'endP';
		me.anchor.endP = me.mixins.anchor.init(me, anchorConfig).hide();
		me.initSelectBox(me);
		me.initLineXY(me);
		me.widget.hide();
		me.selected = [];
		me.target = null;
		me.modelSet = null;
		me.start = null;
		me.end = null;
		me.paper.setStart();
	},
	createId: function(canvas, type, id) {
		var me = canvas || this;
		if (!id) {
			id = type + '-' + (++me.nowId);
		}
		while (Ext.Array.contains(me.modelIds, id)) {
			id = type + '-' + (++me.nowId);
		}
		me.modelIds.push(id);
		return id;
	},
	getModel: function(canvas, e, t, xy) {
		var model, canvas = canvas || this;
		if (t.raphael) {
			model = canvas.paper.getById(t.raphaelid);
		} else {
			xy = xy ? xy : e.getXY();
			model = canvas.paper.getElementByPoint(xy[0], xy[1])
		}
		if (model && model.type === 'text' && model.model) {
			model = model.model;
		} else if (model && model.type === 'path' && model.flow) {
			model = model.flow;
		}
		return model;
	},
	setData: function(canvas, key, value) {
		if (key && value) {
			if (canvas.selected.length == 1) {
				canvas.selected[0].data(key, value);
			} else {
				canvas.data[key] = value;
			}
			return true;
		} else if (key && (typeof key === 'object')) {
			if (canvas.selected.length == 1) {
				canvas.selected[0].data(key);
			} else {
				Ext.apply(canvas.data, key);
			}
			return true;
		} else {
			return false;
		}
	},
	getData: function(canvas, key) {
		var data;
		if (key) {
			if (canvas.selected.length == 1) {
				data = canvas.selected[0].data(key);
			} else {
				data = canvas.data[key];
			}
			return data;
		} else {
			if (canvas.selected.length == 1) {
				data = canvas.selected[0].data();
			} else {
				data = canvas.data;
			}
			return data;
		}
	},
	removeData: function(model, key) {
		if (model && key) {
			model.removeData(key);
			return true;
		} else if (model) {
			model.removeData();
			return true;
		} else {
			return false;
		}
	},
	afterRender: function() {
		var me = this;
		me.callParent();
		if (!me.readOnly) {
			me.el.on('dblclick', me.onDblClick, me);
			me.el.on('mousedown', me.onMousedown, me);
			me.el.on('mousemove', me.onMousemove, me);
			me.el.on('mouseup', me.onMouseup, me);
			me.initKeyMap(me);
		}
	},
	onDblClick: function(e, t) {
		var me = this, textView = me.textView, xy = e.getXY(), model;
		xy[0] += me.body.dom.scrollLeft;
		xy[1] += me.body.dom.scrollTop;
		if (model = me.getModel(me, e, t)) {
			me.selectModel(me, model);
			textView.show();
			textView.setXY(xy);
			textView.focus();
		}
	},
	onMousedown: function(e, t) {
		var me = this, xy = e.getXY(), model = me.getModel(me, e, t), cmp = me.getChildByElement(t),
				dom = me.body.dom;
		if (
				(dom.clientWidth >= dom.offsetWidth - 2 || (dom.clientWidth < dom.offsetWidth - 2 && xy[0] < me.getX() + me.getWidth() - 20))
				&& (dom.clientHeight >= dom.offsetHeight - 2 || (dom.clientHeight < dom.offsetHeight - 2 && xy[1] < me.getY() + me.getHeight() - 20))
				) {
			xy[0] += me.body.dom.scrollLeft;
			xy[1] += me.body.dom.scrollTop;
			if (!(cmp === me.textView || cmp === me.quickbar || cmp === me.widget)) {
				if (model && (me.anchor.hasOwnProperty(model.id) || Ext.Array.contains(me.anchor.knuckles, model))) {
					return;
				} else {
					if (!Ext.Array.contains(me.selected, model)) {
						me.selectModel(me, model);
					}
					if (!model) {
						me.setAnchor(me, me.selectBox, xy);
					} else {
						var selectBox = me.selectBox;
						me.takeUp = model;
						if (!selectBox.view) {
							me.selectModel(me, model);
						}
					}
					me.mousedown = true;
				}
			}
		}
	},
	onMousemove: function(e, t) {
		var me = this;
		if (me.mousedown && me.selectBox.view && !me.takeUp) {
			var xy = e.getXY();
			xy[0] += me.body.dom.scrollLeft;
			xy[1] += me.body.dom.scrollTop;
			me.changeSelectBox(me, me.selectBox, xy);
			me.mousemove = true;
		}
	},
	onMouseup: function(e, t) {
		var me = this, cmp = me.getChildByElement(t), dom = me.body.dom, xy = e.getXY();
		if (
				(dom.clientWidth >= dom.offsetWidth - 2 || (dom.clientWidth < dom.offsetWidth - 2 && xy[0] < me.getX() + me.getWidth() - 20))
				&& (dom.clientHeight >= dom.offsetHeight - 2 || (dom.clientHeight < dom.offsetHeight - 2 && xy[1] < me.getY() + me.getHeight() - 20))
				) {
			me.target = null;
			if (me.selected.length == 1 && me.selected[0].type !== 'path') {
				var bbox = me.selectBox.getBBox();
				me.widget.show();
				me.widget.setXY([
					bbox.x2 + me.origin.offsetX + 2 - me.body.dom.scrollLeft,
					bbox.y + me.origin.offsetY - me.body.dom.scrollTop
				]);
			}
			if (!(me.textView.focused || cmp === me.textView || cmp === me.quickbar || cmp === me.widget)) {
				if (me.selected.length == 1 && t.raphael && me.selected[0].id !== t.raphaelid) {
					me.target = me.getModel(me, e, t);
				}
				if (me.selectBox.view && !me.takeUp && !me.target) {
					me.selectModel(me);
				}
			}
			me.takeUp = null;
			me.mousemove = false;
			me.mousedown = false;
		}
	},
	initKeyMap: function(me) {
		Ext.create('Ext.util.KeyMap', {
			target: me.getId(),
			ctrl: true,
			key: Ext.EventObject.C,
			canvas: me,
			fn: function(key, ev) {
				this.canvas['ctrl+c'](this.canvas);
				ev.stopEvent();
				return false;
			}
		});
		Ext.create('Ext.util.KeyMap', {
			target: me.getId(),
			ctrl: true,
			key: Ext.EventObject.V,
			canvas: me,
			fn: function(key, ev) {
				this.canvas['ctrl+v'](this.canvas);
				ev.stopEvent();
				return false;
			}
		});
		Ext.create('Ext.util.KeyMap', {
			target: me.getId(),
			key: Ext.EventObject.DELETE,
			canvas: me,
			fn: function(key, ev) {
				this.canvas['del'](this.canvas);
				ev.stopEvent();
				return false;
			}
		});
		Ext.create('Ext.util.KeyMap', {
			target: me.getId(),
			ctrl: true,
			key: Ext.EventObject.A,
			canvas: me,
			fn: function(key, ev) {
				this.canvas['ctrl+a'](this.canvas);
				ev.stopEvent();
				return false;
			}
		});
	}
});